﻿#include <iostream>
using namespace std;

double Division(int a, int b)
{
	if (b == 0)
	{
		throw "Division by zero condition!!!";
	}
	try
	{
		fxx(a, b);
	}
	catch (const char* errmsg)//类型不匹配不选择
	{
		cout << errmsg << endl;
	}
	catch (int x)//优先跳到最近的捕获
	{
		cout << "捕获异常:" << x << endl;
	}
	return ((double)a / (double)b);
}

double fxx(int a, int b)
{
	int i;
	cin >> i;
	if (i % 2 == 0)
	{
		throw 1;//如果没有合适的捕获会报错
	}
	if (i % 3 == 0)
	{
		string s("出现异常\n");
		throw s;//传的是一个拷贝值“右值”
	}
	return ((double)a / (double)b / (double)i);
}

void Func()
{
	int len, time;
	cin >> len >> time;
	cout << Division(len, time) << endl;
}

int main()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch (int x)//可以有多个捕获
	{
		cout << "捕获异常" << endl;
	}
	catch (string& s)
	{
		cout << s << endl;
	}
	catch (...)//捕获任意类型异常，做最后一层保障，仅能记录异常但不知道位置
	{
		cout << "未知异常" << endl;
	}
	return 0;
}

// 服务器开发中通常使用的异常继承体系
class Exception
{
public:
	Exception(const string& errmsg, int id)
		:_errmsg(errmsg)
		, _id(id)
	{}
	virtual string what() const
	{
		return _errmsg;
	}
protected:
	string _errmsg;
	int _id;
};
class SqlException : public Exception
{
public:
	SqlException(const string& errmsg, int id, const string& sql)
		:Exception(errmsg, id)
		, _sql(sql)
	{}
	virtual string what() const
	{
		string str = "SqlException:";
		str += _errmsg;
		str += "->";
		str += _sql;
		return str;
	}
private:
	const string _sql;
};
class CacheException : public Exception
{
public:
	CacheException(const string& errmsg, int id)
		:Exception(errmsg, id)
	{}
	virtual string what() const
	{
		string str = "CacheException:";
		str += _errmsg;
		return str;
	}
};
class HttpServerException : public Exception
{
public:
	HttpServerException(const string& errmsg, int id, const string& type)
		:Exception(errmsg, id)
		, _type(type)
	{}
	virtual string what() const
	{
		string str = "HttpServerException:";
		str += _type;
		str += ":";
		str += _errmsg; return str;
	}
private:
	const string _type;
};
void SQLMgr()
{
	srand(time(0));
	if (rand() % 7 == 0)
	{
		throw SqlException("权限不足", 100, "select * from name = '张三'");
	}
	//throw "xxxxxx";
}
void CacheMgr()
{
	srand(time(0));
	if (rand() % 5 == 0)
	{
		throw CacheException("权限不足", 100);
	}
	else if (rand() % 6 == 0)
	{
		throw CacheException("数据不存在", 101);
	}
	SQLMgr();
}
void HttpServer()
{
	// ...
	srand(time(0));
	if (rand() % 3 == 0)
	{
		throw HttpServerException("请求资源不存在", 100, "get");
	}
	else if (rand() % 4 == 0)
	{
		throw HttpServerException("权限不足", 101, "post");
	}
	CacheMgr();
}
int main()
{
	while (1)
	{
		//this_thread::sleep_for(chrono::seconds(1));
		try {
			HttpServer();
		}
		//5.C++标准库的异常体系
		//	C++ 提供了一系列标准的异常，定义在  中，我们可以在程序中使用这些标准的异常。它们是以父
		//	子类层次结构组织起来的，如下所示：
			catch (const Exception& e) // 这里捕获父类对象就可以
		{
			// 多态
			cout << e.what() << endl;
		}
		catch (...)
		{
			cout << "Unkown Exception" << endl;
		}
	}
	return 0;
}